package com.ruoyi.applet.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.applet.domain.AppletTeam;
import com.ruoyi.applet.domain.AppletUserStep;
import com.ruoyi.applet.domain.AppletWalkRow;
import com.ruoyi.applet.domain.WechatUser;
import com.ruoyi.applet.mapper.AppletTeamMapper;
import com.ruoyi.applet.mapper.AppletWalkRowMapper;
import com.ruoyi.applet.mapper.WechatUserMapper;
import com.ruoyi.applet.service.IAppletWalkRowService;
import com.ruoyi.applet.service.IWechatUserService;
import com.brisk.common.core.domain.AjaxResult;
import com.brisk.common.core.redis.RedisCache;
import com.brisk.common.utils.DateUtils;
import com.brisk.common.utils.SecurityUtils;
import com.brisk.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * appletWalkRowService业务层处理
 *
 * @author PENGFEIDENG
 * @date 2022-06-01
 */
@Service
public class AppletWalkRowServiceImpl implements IAppletWalkRowService {
    @Autowired
    private AppletWalkRowMapper appletWalkRowMapper;

    @Autowired
    private WechatUserMapper wechatUserMapper;

    @Autowired
    private AppletTeamMapper appletTeamMapper;

    @Autowired
    private IWechatUserService wechatUserService;

    @Autowired
    private RedisCache redisCache;


    /**
     * 查询appletWalkRow
     *
     * @param rowId appletWalkRow主键
     * @return appletWalkRow
     */
    @Override
    public AppletWalkRow selectAppletWalkRowByRowId(Long rowId) {
        return appletWalkRowMapper.selectAppletWalkRowByRowId(rowId);
    }

    @Override
    public AppletWalkRow selectTodayAppletWalkRowByUserId(Long userId) {
        return appletWalkRowMapper.selectTodayAppletWalkRowByRowId(userId);
    }

    /**
     * 查询appletWalkRow列表
     *
     * @param appletWalkRow appletWalkRow
     * @return appletWalkRow
     */
    @Override
    public List<AppletWalkRow> selectAppletWalkRowList(AppletWalkRow appletWalkRow) {
        return appletWalkRowMapper.selectAppletWalkRowList(appletWalkRow);
    }

    @Override
    public List<AppletWalkRow> selectTodayAppletWalkRowList(AppletWalkRow appletWalkRow) {
        return appletWalkRowMapper.selectTodayAppletWalkRowList(appletWalkRow);
    }

    @Override
    public Map<String, Object> getWalkRowChar() {
        List<String> xData = new ArrayList<>(); // 横坐标 纵坐标
        List<BigDecimal> mileage = new ArrayList<>(); //兑换里程数
        List<Long> covertSum = new ArrayList<>(); //兑换步数
        List<Long> stepSum = new ArrayList<>();  //微信步数
        List<AppletWalkRow> rowList = appletWalkRowMapper.getWalkRowChar();
        int size = Math.min(rowList.size(), 10);
        for (int i = size - 1; i >= 0; i--) {
            AppletWalkRow temp = rowList.get(i);
            xData.add(DateUtils.parseDateToStr("MM-dd", temp.getRowTime()));
            mileage.add(new BigDecimal(temp.getAgoWalk()).divide(new BigDecimal(20), 2, RoundingMode.FLOOR));
            covertSum.add(Long.valueOf(temp.getAgoWalk()));
            stepSum.add(Long.valueOf(temp.getNowWalk()));
        }
        Map<String, Object> res = new HashMap<>();
        res.put("xData", xData);
        res.put("mileage", mileage);
        res.put("covertSum", covertSum);
        res.put("stepSum", stepSum);
        return res;
    }

    /**
     * 新增appletWalkRow
     *
     * @param appletWalkRow appletWalkRow
     * @return 结果
     */
    @Override
    public int insertAppletWalkRow(AppletWalkRow appletWalkRow) {
        appletWalkRow.setCreateTime(DateUtils.getNowDate());
        return appletWalkRowMapper.insertAppletWalkRow(appletWalkRow);
    }

    /**
     * 修改appletWalkRow
     *
     * @param appletWalkRow appletWalkRow
     * @return 结果
     */
    @Override
    public int updateAppletWalkRow(AppletWalkRow appletWalkRow) {
        appletWalkRow.setUpdateTime(DateUtils.getNowDate());
        return appletWalkRowMapper.updateAppletWalkRow(appletWalkRow);
    }

    /**
     * 批量删除appletWalkRow
     *
     * @param rowIds 需要删除的appletWalkRow主键
     * @return 结果
     */
    @Override
    public int deleteAppletWalkRowByRowIds(Long[] rowIds) {
        return appletWalkRowMapper.deleteAppletWalkRowByRowIds(rowIds);
    }

    /**
     * 删除appletWalkRow信息
     *
     * @param rowId appletWalkRow主键
     * @return 结果
     */
    @Override
    public int deleteAppletWalkRowByRowId(Long rowId) {
        return appletWalkRowMapper.deleteAppletWalkRowByRowId(rowId);
    }

    @Override
    @Transactional
    public AjaxResult addUserConvert(Long userId) {
        WechatUser wechatUser = wechatUserMapper.selectWechatUserByUserId(userId);
        if (ObjectUtils.isEmpty(wechatUser)) return AjaxResult.error("获取用户信息失败!");
        //没有加入队伍，不可兑换
        if (null == wechatUser.getTeamId()) return AjaxResult.error("您未加入任何队伍，无法兑换！");
        AppletWalkRow walkRow = appletWalkRowMapper.selectTodayAppletWalkRowByRowId(userId);
        //判断今天是否同步了微信数据
        if (ObjectUtils.isEmpty(walkRow)) return AjaxResult.error("获取用户步数信息失败!");
        //判断用户今天是否兑换了  兑换步数大于0 表示今天已经兑换了 不能再兑换
        if (walkRow.getAgoWalk() > 0) return AjaxResult.error("兑换失败，一天只能兑换一次！");
        //计算用户可用步数 小于6000不给兑换  兑换大于 6000 步 才可以兑换
        int convertSum = walkRow.getNowWalk() - walkRow.getAgoWalk();
        if (convertSum < 6000) return AjaxResult.error("兑换失败，最少兑换步数需要6000步！");
        //计算用户可用里程数  20 步 等于 1里  客户说  这个写死 不会变
        BigDecimal mileage = new BigDecimal(convertSum).divide(new BigDecimal(20), 2, RoundingMode.HALF_UP);
        //更新用户里程数
        WechatUser update = new WechatUser();
        update.setUserId(userId);
        update.setMileage(mileage);
        if (walkRow.getAgoWalk() == 0) update.setDaySum(1);  // 如果没有兑换  那么就是用户第一次兑换 兑换天数要加1
        int res = wechatUserMapper.updateUserNumberByUserId(update);
        if (res > 0) { //更新用户微信步数
            AppletWalkRow updateRow = new AppletWalkRow();
            updateRow.setRowId(walkRow.getRowId());
            updateRow.setAgoWalk(walkRow.getNowWalk());
            int res1 = appletWalkRowMapper.updateAppletWalkRow(updateRow);
            AppletTeam updateTeam = new AppletTeam();
            updateTeam.setTeamId(wechatUser.getTeamId());
            updateTeam.setWalkSum(mileage);
            int res2 = appletTeamMapper.updateAppletTeamSum(updateTeam);
            if (res1 > 0 && res2 > 0) {
                //删除用户缓存
                redisCache.deleteObject(wechatUser.getOpenid() + "_run_data_2");
                AjaxResult userConvertInfo = wechatUserService.getUserConvertInfo(userId);
                String msg = "您使用了" + convertSum + "步兑换了" + mileage + "里程";
                return AjaxResult.success(msg, userConvertInfo.get("data"));

            }
            return AjaxResult.error("兑换失败！");
        }
        return AjaxResult.error("兑换失败！");
    }

    @Override
    public AjaxResult updateUserStep(List<AppletUserStep> stepList, WechatUser wechatUser) {
        //去第一条数据就是今天的
        AppletUserStep userStep = stepList.get(0);
        System.out.println("更新微信步数接口获取第一条用户数据数据：");
        System.out.println(userStep);
        //查询今天是否有数据是否有数据
        AppletWalkRow todayRow = appletWalkRowMapper.selectTodayAppletWalkRowByRowId(wechatUser.getUserId());
        int res;
        if (ObjectUtils.isEmpty(todayRow)) {
            AppletWalkRow insert = new AppletWalkRow();
            insert.setUserId(wechatUser.getUserId());
            insert.setNickName(wechatUser.getUserName() == null ? wechatUser.getUserNickname() : wechatUser.getUserName());
            insert.setAvatarUrl(wechatUser.getUserImg());
            insert.setRowTime(new Date(userStep.getTimestamp()));
            insert.setUserName(wechatUser.getUserName() == null ? wechatUser.getUserNickname() : wechatUser.getUserName());
            insert.setAgoWalk(0);
            insert.setNowWalk(userStep.getStep());
            insert.setCreateTime(DateUtils.getNowDate());
            res = appletWalkRowMapper.insertAppletWalkRow(insert);
        } else {
            AppletWalkRow update = new AppletWalkRow();
            update.setRowId(todayRow.getRowId());
            update.setNowWalk(userStep.getStep());
            res = appletWalkRowMapper.updateAppletWalkRow(update);
        }
        AppletWalkRow appletWalkRow = appletWalkRowMapper.selectTodayAppletWalkRowByRowId(wechatUser.getUserId());
        int step = appletWalkRow.getNowWalk() - appletWalkRow.getAgoWalk();
        step = step > 0 ? step : 1;
        System.out.println("重新请求微信运动数据解密更新成功！返回数据---->" + step);
        redisCache.setCacheObject(wechatUser.getOpenid() + "_run_data_2", step); //设置过期时间 用于更新
        redisCache.expire(wechatUser.getOpenid() + "_run_data_2", 10 * 60);
        return res > 0 ? AjaxResult.success("更新成功", step) : AjaxResult.error("更新步数失败");
    }

    @Override
    public AjaxResult getUserECharsData() {
        WechatUser wechatUser = wechatUserMapper.selectWechatUserByUserId(SecurityUtils.getUserId());
        if (ObjectUtils.isEmpty(wechatUser)) return AjaxResult.error("获取用户信息失败！");
        String cacheData = redisCache.getCacheObject(wechatUser.getOpenid() + "_run_data");
        if (StringUtils.isEmpty(cacheData)) return AjaxResult.error("获取数据失败");
        List<AppletUserStep> userStepList = getUserStep(cacheData);
        if (null == userStepList || userStepList.size() == 0) return AjaxResult.error("获取微信步数失败");
        Map<String, Map<String, Object>> result = getEchartsData(userStepList);
        return AjaxResult.success(result);
    }


    public List<AppletUserStep> getUserStep(String weRunData) {
        JSONObject userRunData = JSON.parseObject(weRunData); //格式化成JSON对象
        JSONArray userStepArray = userRunData.getJSONArray("stepInfoList"); //获取用户运动数据
        List<AppletUserStep> userStepList = new ArrayList<>(); //存放用户的数据
        for (int i = 0; i < userStepArray.size(); i++) {
            JSONObject temp = userStepArray.getJSONObject(i);
            Integer step = temp.getInteger("step");
            Long timestamp = temp.getLong("timestamp");
            AppletUserStep userStep = new AppletUserStep();
            userStep.setStep(step);
            userStep.setTimestamp(timestamp * 1000);
            userStep.setRowData(DateUtils.parseDateToStr("yyyy-MM-dd", new Date(userStep.getTimestamp())));
            userStepList.add(userStep);
        }
        //按日期排序
        userStepList = userStepList.stream().sorted((a, b) -> b.getTimestamp().compareTo(a.getTimestamp())).collect(Collectors.toList());
        return userStepList;
    }


    @Override
    public int getUserRankInList(Long userId) {
        Integer rank = appletWalkRowMapper.getUserRankInList(userId);
        return rank == null ? 0 : rank;
    }

    //解析数据
    public Map<String, Map<String, Object>> getEchartsData(List<AppletUserStep> userStepList) {
        Map<String, Map<String, Object>> result = new HashMap<>();
        Map<String, Object> tableData = new HashMap<>();
        //表格数据
        tableData.put("title", "最近30天步数明细");
        tableData.put("tableData", userStepList);
        int todayStep = 0;
        int weekStep = 0;
        int monthStep = 0;
        List<String> weekXData = new ArrayList<>();
        List<Integer> weekYData = new ArrayList<>();
        List<String> monthXData = new ArrayList<>();
        List<Integer> monthYData = new ArrayList<>();
        //今日数据
        AppletUserStep userStep = userStepList.get(0);
        if (DateUtils.getDate().equalsIgnoreCase(userStep.getRowData())) {
            todayStep = userStep.getStep();
        }

        //数组折线图  要升序
        userStepList = userStepList.stream().sorted(Comparator.comparing(AppletUserStep::getTimestamp)).collect(Collectors.toList());
        for (int i = 0; i < userStepList.size(); i++) {
            AppletUserStep temp = userStepList.get(i);
            //近7天 已经升序 总共31条数据 从下标 24 开始到结尾就是近7天
            if (i > userStepList.size() - 8) {
                weekStep += temp.getStep();
                weekXData.add(temp.getRowData().substring(5));
                weekYData.add(temp.getStep());
            }
            monthStep += temp.getStep();
            monthXData.add(temp.getRowData().substring(5));
            monthYData.add(temp.getStep());
        }

        Map<String, Object> todayData = new HashMap<>();
        todayData.put("title", "顶部数据");
        todayData.put("todayStep", todayStep);
        todayData.put("weekStep", weekStep);
        todayData.put("monthStep", monthStep);
        Map<String, Object> weekLine = new HashMap<>();
        weekLine.put("title", "最近7天步数");
        weekLine.put("weekXData", weekXData);
        weekLine.put("weekYData", weekYData);
        Map<String, Object> monthLine = new HashMap<>();
        monthLine.put("title", "最近30天步数");
        monthLine.put("monthXData", monthXData);
        monthLine.put("monthYData", monthYData);

        result.put("todayData", todayData);
        result.put("weekLine", weekLine);
        result.put("monthLine", monthLine);
        result.put("tableData", tableData);
        return result;
    }


}
